﻿<cfscript>
/** 
* @hint "markManager - StudentMark, StudentMarkAduit"
*/ 

component 
	extends="MachII.framework.Listener" 
	displayname="acadmicManager.listeners.senate.studentMarkListener" 
	output=false 
	depends="sessionAdvice, datetimeAdvice, securityAdvice, markAdvice, creditFactory, sequenceStudentMark, sequenceStudentMarkAduit, logFactory" 
	{
	
	/**
	* @hint "Configures this listener as part of the Mach-II framework"
	*/
	public void function configure() output=false {} 
	
	/**
	* @hint "学生本人刷新修读课程绩点"
	* 
	* @event "MachII Event Object"
	*/
	public void function flushStudentMarkCreditPoint( required MachII.framework.Event event ) output=false {

		var creditFactory = getcreditFactory();
		
		var studentId = event.getArg("STU");

		if ( len(studentId) ) {

			/* 刷新指定学生的学分统计数据 */
			creditFactory.creditRefresh( studentId ); 

		}

	}
	
	/**
	* @hint "录入学生成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function createMark( required MachII.framework.Event event ) output=false {
		
		var sequenceStudentMark = getsequenceStudentMark();
		var sequenceStudentMarkAduit = getsequenceStudentMarkAduit();
		
		var courseId = event.getArg("CourseID");
		var studentId = event.getArg("StudentID");
		var propId = event.getArg("PropID");
		var taskType = event.getArg("TaskType");
		var termId = event.getArg("TermY") & event.getArg("TermT");
		
		var tchId = getsessionAdvice().getAutherUserID();
		
		var currentTS = getdatetimeAdvice().getCurrentDatetimeString();
		var currentIP = getsecurityAdvice().getIP();
		
		var markAdvice = getmarkAdvice();
		
		var sql = ""; 
		var queryObj = ""; 
		
		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			sql = "SELECT academic_year, academic_term FROM t_term WHERE term_id = :termId ";
		
			queryObj = new Query( datasource=application.dnsSlave );
			queryObj.addParam( name="termId", value=termId, cfsqltype="cf_sql_char" );
			
			rs_term = queryObj.execute( sql=sql ).getResult();
			
			
			sql = "SELECT tch_name FROM t_teacher WHERE tch_id = :tercherId ";
		
			queryObj = new Query( datasource=application.dnsSlave );
			queryObj.addParam( name="tercherId", value=tchId, cfsqltype="cf_sql_varchar" );
			
			rs_teacher = queryObj.execute( sql=sql ).getResult();
			
			sql = "SELECT mark_mode, course_name, course_credit FROM t_course  WHERE cid = :courseId ";
						
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="courseId", value=courseId, cfsqltype="cf_sql_varchar" );
			
			rs_course = queryObj.execute( sql=sql ).getResult();

			var courseCredit = rs_course.course_credit;
		
			var markMode = rs_course.mark_mode;

			var mark = event.getArg("Mark");
			var markNote = event.getArg("MarkNote");
			
			var markResit = event.getArg("MarkResit", -1);
			var markResitNote = event.getArg("MarkResitNote");
			
			var scroll = -1;
			var scrollResit = -1;
			var markResitLimit = 100;
			
			
			
			/* 根据成绩备注矫正分数 */
			if ( markNote eq "2" ) { /* 2 - 缺考 */ scroll = -1; }
			if ( markNote eq "3" ) { /* 3 - 缓考 */ scroll = -1; }
			if ( markNote eq "4" ) { /* 4 - 免修 */ scroll = -1; }
			if ( markNote eq "9" ) { /* 9 - 违纪 */ scroll = 0; }
			
			/* 根据成绩计分模式调整分数 */
			switch ( markMode ) {
				
				case "0":
					/* 百分制最多保留2位小数 */
					if ( markNote eq "1" ) {
						scroll = round( mark * 10 ) / 10;
					}					
					break;
					
				case "2":
					/* 二级制则转换 Y N */
					if ( markNote eq "Y" ) {
						scroll = 60; 
						markNote = "1";
					}
					else if ( markNote eq "N" ) {
						scroll = 0; 
						markNote = "1";
					}
					break;
					
				case "4":
					/* 五级制则转换 A B C D */
					if ( markNote eq "A" ) {
						scroll = 95; 
						markNote = "1";
					}
					else if ( markNote eq "B" ) {
						scroll = 85; 
						markNote = "1";
					}
					else if ( markNote eq "C" ) {
						scroll = 75; 
						markNote = "1";
					}
					else if ( markNote eq "D" ) {
						scroll = 65; 
						markNote = "1";
					}else if ( markNote eq "E" ) {
						scroll = 0; 
						markNote = "1";
					}
					break;
				
			}
			
			/* 若成绩备注为 缓考 则设置 补考成绩上限为最大值 */
			if ( markNote eq "3" ) { /* 3 - 缓考 */ 
				markResitLimit =  100 ;
			}
			
			/* 根据补考成绩备注矫正分数 */
			if ( markResitNote eq "2" ) { /* 2 - 缺考 */ scrollResit = 0; }
			if ( markResitNote eq "9" ) { /* 9 - 违纪 */ scrollResit = 0; }
			
			/* 根据补考成绩计分模式调整分数 */
			switch ( markMode ) {
				
				case "0":
					/* 百分制最多保留2位小数 */
					if ( markResitNote eq "1" ) {
						scrollResit = round( markResit * 10 ) / 10;
					}
					break;
					
				case "2":
					/* 二级制则转换 Y N */
					if ( markResitNote eq "Y" ) {
						scrollResit = 60; 
						markResitNote = "1";
					}
					else if ( markResitNote eq "N" ) {
						scrollResit = 0; 
						markResitNote = "1";
					}
					break;
					
				case "4":
					/* 五级制则转换 A B C D */
					if ( markNote eq "A" ) {
						scrollResit = 95; 
						markResitNote = "1";
					}
					else if ( markNote eq "B" ) {
						scrollResit = 85; 
						markResitNote = "1";
					}
					else if ( markNote eq "C" ) {
						scrollResit = 75; 
						markResitNote = "1";
					}
					else if ( markNote eq "D" ) {
						scrollResit = 65; 
						markResitNote = "1";
					}else if ( markNote eq "E" ) {
						scrollResit = 0; 
						markResitNote = "1";
					}
					break;
				
			}
			
			if( scroll lt 60 AND scrollResit lt 60){
				courseCredit = 0;	
			}
			
			/* 如果没有补考成绩 */
			if ( markResitNote eq "0" ) { /* 0 - 没有补考成绩 */ scrollResit = -1; markResitNote = 1; }

			
			/* 第一步 生成成绩变更审计记录 */		
			var logId = sequenceStudentMarkAduit.getNextID();
			
			var description = "录入 " & rs_term.academic_year & "-" & rs_term.academic_term & "学期《" & rs_course.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( markMode, scroll, markNote ) & " 补考成绩 " & markAdvice.getMarkResit( markMode, scrollResit,markResitNote, markResitLimit );
			
			/* 若无补考成绩, 则修正日志 */
			if ( markAdvice.getMarkResit( markMode, scrollResit, markResitNote, markResitLimit ) eq "" ) {
				description = "录入 " & rs_term.academic_year & "-" & rs_term.academic_term & "学期《" & rs_course.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( markMode, scroll, markNote ) ;
			}
			
			sql = "INSERT INTO t_mark_aduit(
								opid, tch_id, 
								stu_id, cid, 
								op_type, op_ts, 
								op_ip, operation
							)VALUES(
								:operId, :teacherId, 
								:studentId, :courseId, 
								:operation, :timeStamp, 
								:ip, :description
							)";
			
			queryObj = new Query( datasource=application.dnsMaster );

			queryObj.addParam( name="operId", value=logId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="courseId", value=courseId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="operation", value="ADD", cfsqltype="cf_sql_char" );
			queryObj.addParam( name="timeStamp", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="ip", value=currentIP, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="description", value=description, cfsqltype="cf_sql_varchar" );
			
			queryObj.execute( sql=sql );

			
			/* 第二步 变更成绩历史记录 */
			sequenceStudentMark.setStudentID(studentId);
			sequenceStudentMark.setCourseID(courseId);
			sequenceStudentMark.setTermID(termId);
			sequenceStudentMark.setTaskType(taskType);
			
			var markId = sequenceStudentMark.getID();
			
			var bookedcourseId = sequenceStudentMark.getBoodedCourseId();
			
			sql = "INSERT INTO t_student_mark(
								scm_id, stu_id, term_id, cid, prop_id, retaking, 
								mark_mode, mark_result, mark_note, mark_resit, mark_renote,
								task_type, task_id, tch_id, mark_time,
								mark_resit_time, scc_id, mark_resit_limit, remarks, credit_point,
								term_score, makeup_score, credit, GRADE_POINT, CREDIT_POINT_O, BOOKEDCOURSE_ID
						  )VALUES(
								:markId, :studentId, :termId, :courseId, :propId, :retaking, 
								:markMode, :markResult, :markNote, :markResit, :markResitNote, 
								:taskType, :taskId, :teacherId, :markTime, 
								:markResitTime, :chooseId, :markResitLimit, :remarks, :creditPoint ,
								:termScore, :makeupScore, :credit, :gradePoint, :creditPoint_o, :bookedCourseId
						  )"; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="termId", value=termId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="courseId", value=courseId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="propId", value=propId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="retaking", value=event.getArg("Retaking"), cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markMode", value=markMode, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResult", value=scroll, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="markNote", value=markNote, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResit", value=scrollResit, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="markResitNote", value=markResitNote, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="taskType", value=taskType, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="taskId", value=termId & "," & courseId & ",ADD", cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="markTime", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResitTime", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="chooseId", value=studentId & "," & courseId & "," & termId & taskType, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="markResitLimit", value=markResitLimit, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="remarks", value=rs_teacher.tch_name & " 在 " & getdatetimeAdvice().getDateTime() & " 手工录入", cfsqltype="cf_sql_varchar" );
			
			queryObj.addParam( name="creditPoint", value=markAdvice.getMarkCredit(markMode, courseCredit, scroll, scrollResit, markResitLimit), cfsqltype="cf_sql_decimal", scale=4 );
			queryObj.addParam( name="termScore", value=scroll, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="makeupScore", value=scrollResit, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="credit", value=courseCredit, cfsqltype="cf_sql_integer" );
			queryObj.addParam( name="gradePoint", value=markAdvice.getMarkCredit(markMode, courseCredit, scroll, scrollResit, markResitLimit), cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="creditPoint_o", value=courseCredit * markAdvice.getMarkCredit(markMode, courseCredit, scroll, scrollResit, markResitLimit), cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="bookedCourseId", value=bookedcourseId, cfsqltype="cf_sql_integer" );
			
			queryObj.execute( sql=sql );
			
			var passArgs = structNew();
			structInsert( passArgs, "STU", studentId, true );

			event.setArgs( passArgs );
			
			
			
		}
		
	}
	
	
	
	/**
	* @hint "批量删除成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function removeMarks( required MachII.framework.Event event ) output=false {
		
		var sequenceStudentMarkAduit = getsequenceStudentMarkAduit();
		
		var markIds = event.getArg("SMIDs");
		var markArray = listToArray( markIds, "|" );
		
		var sql = ""; 
		var queryObj = "";
		
		transaction {
		
			for( var markId in markArray ){
				
				var tchId = getsessionAdvice().getAutherUserID();
				
				var currentTS = getdatetimeAdvice().getCurrentDatetimeString();
				var currentIP = getsecurityAdvice().getIP();
				
				var markAdvice = getmarkAdvice();
			
				/* Every SQL operation is TRANSACATION*/

				sql = "SELECT 
							 t_student_mark.stu_id, 
							 t_term.academic_year, 
							 t_term.academic_term, 
							 t_course.course_name, 
							 t_student_mark.mark_mode, 
							 t_student_mark.mark_result, 
							 t_student_mark.mark_note, 
							 t_student_mark.mark_resit, 
							 t_student_mark.mark_renote, 
							 t_student_mark.mark_resit_limit, 
							 t_student_mark.cid 
						FROM 
							 t_student_mark ,t_term ,t_course 
						WHERE
							 t_course.cid = t_student_mark.cid
							 AND 
							 t_term.term_id = t_student_mark.term_id 
							 AND  
							 t_student_mark.scm_id = :markId "; 
				
				queryObj = new Query( datasource=application.dnsMaster );
				queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
				
				var rs_markEntity = queryObj.execute( sql=sql ).getResult();
				
				var studentId = rs_markEntity.stu_id;
				
				
				/* 第一步 生成成绩变更审计记录 */
				var logId = sequenceStudentMarkAduit.getNextID();
			
				var description = "删除 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( rs_markEntity.mark_mode, rs_markEntity.mark_result, rs_markEntity.mark_note ) & " 补考成绩 " & markAdvice.getMarkResit( rs_markEntity.mark_mode, rs_markEntity.mark_resit, rs_markEntity.mark_renote, rs_markEntity.mark_resit_limit );
				
				/* 若无补考成绩, 则修正日志 */
				if ( markAdvice.getMarkResit( rs_markEntity.mark_mode, rs_markEntity.mark_resit, rs_markEntity.mark_renote, rs_markEntity.mark_resit_limit ) eq "" ) {
					description = "删除 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( rs_markEntity.mark_mode, rs_markEntity.mark_result, rs_markEntity.mark_note );
				}
				
				sql = "INSERT INTO t_mark_aduit(
									opid, tch_id, 
									stu_id, cid, 
									op_type, op_ts, 
									op_ip, operation
								)VALUES(
									:operId, :teacherId, 
									:studentId, :courseId, 
									:operation, :timeStamp, 
									:ip, :description
								)";
				
				queryObj = new Query( datasource=application.dnsMaster );
				queryObj.addParam( name="operId", value=logId, cfsqltype="cf_sql_char" );
				queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
				queryObj.addParam( name="studentId", value=rs_markEntity.stu_id, cfsqltype="cf_sql_varchar" );
				queryObj.addParam( name="courseId", value=rs_markEntity.cid, cfsqltype="cf_sql_varchar" );
				queryObj.addParam( name="operation", value="RMA", cfsqltype="cf_sql_char" );
				queryObj.addParam( name="timeStamp", value=currentTS, cfsqltype="cf_sql_char" );
				queryObj.addParam( name="ip", value=currentIP, cfsqltype="cf_sql_varchar" );
				queryObj.addParam( name="description", value=description, cfsqltype="cf_sql_varchar" );
				
				queryObj.execute( sql=sql );
			
			
				/* 第二步 变更成绩历史记录 */
				sql = "DELETE FROM t_student_mark WHERE scm_id = :markId "; 
				
				queryObj = new Query( datasource=application.dnsMaster );
				queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
				
				queryObj.execute( sql=sql );
				
			}
		
			var passArgs = structNew();
			structInsert( passArgs, "STU", studentId, true );
			event.setArgs( passArgs );
			
		}
	}
	
	/**
	* @hint "删除期末考试成绩及补考成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function deleteMark( required MachII.framework.Event event ) output=false {
		
		var sequenceStudentMarkAduit = getsequenceStudentMarkAduit();
		
		var markId = event.getArg("MarkID");
		
		var tchId = getsessionAdvice().getAutherUserID();
		
		var currentTS = getdatetimeAdvice().getCurrentDatetimeString();
		var currentIP = getsecurityAdvice().getIP();
		
		var markAdvice = getmarkAdvice();
		
		var sql = ""; 
		var queryObj = ""; 

		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			sql = "SELECT 
						 t_term.academic_year, 
						 t_term.academic_term, 
						 t_course.course_name, 
						 t_student_mark.mark_mode, 
						 t_student_mark.mark_result, 
						 t_student_mark.mark_note,
						 t_student_mark.mark_resit, 
						 t_student_mark.mark_renote,  
						 t_student_mark.mark_resit_limit, 
						 t_student_mark.stu_id, 
						 t_student_mark.cid 
					FROM 
						 t_student_mark 
						 INNER JOIN t_course ON t_course.cid = t_student_mark.cid 
						 INNER JOIN t_term ON t_term.term_id = t_student_mark.term_id 
					WHERE 
						 t_student_mark.scm_id = :markId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			
			var rs_markEntity = queryObj.execute( sql=sql ).getResult();
			
			var studentId = rs_markEntity.stu_id;
			
			
			/* 第一步 生成成绩变更审计记录 */
			var logId = sequenceStudentMarkAduit.getNextID();

			var description = "删除 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( rs_markEntity.mark_mode, rs_markEntity.mark_result, rs_markEntity.mark_note ) & " 补考成绩 " & markAdvice.getMarkResit( rs_markEntity.mark_mode, rs_markEntity.mark_resit, rs_markEntity.mark_renote, rs_markEntity.mark_resit_limit );
		
			
			/* 若无补考成绩, 则修正日志 */
			if ( markAdvice.getMarkResit( rs_markEntity.mark_mode, rs_markEntity.mark_resit, rs_markEntity.mark_renote, rs_markEntity.mark_resit_limit ) eq "" ) {
				
				description = "删除 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 成绩, 正考成绩 " & markAdvice.getMark( rs_markEntity.mark_mode, rs_markEntity.mark_result, rs_markEntity.mark_note );
			}
			
			sql = "INSERT INTO t_mark_aduit(
								opid, tch_id, 
								stu_id, cid, 
								op_type, op_ts, 
								op_ip, operation
							)VALUES(
								:operId, :teacherId, 
								:studentId, :courseId, 
								:operation, :timeStamp, 
								:ip, :description
							)";
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="operId", value=logId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="studentId", value=rs_markEntity.stu_id, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="courseId", value=rs_markEntity.cid, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="operation", value="RMA", cfsqltype="cf_sql_char" );
			queryObj.addParam( name="timeStamp", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="ip", value=currentIP, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="description", value=description, cfsqltype="cf_sql_varchar" );
			
			queryObj.execute( sql=sql );
			
			
			/* 第二步 变更成绩历史记录 */
			sql = "DELETE FROM t_student_mark WHERE scm_id = :markId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			
			queryObj.execute( sql=sql );
			
			var passArgs = structNew();
			structInsert( passArgs, "STU", studentId, true );

			event.setArgs( passArgs );
			
			
		}
	}
	
	
	/**
	* @hint "更新期末考试成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function updateFinal( required MachII.framework.Event event ) output=false {
		
		var sequenceStudentMarkAduit = getsequenceStudentMarkAduit();
		
		var markId = event.getArg("MarkID");
		
		var tchId = getsessionAdvice().getAutherUserID();
		
		var currentTS = getdatetimeAdvice().getCurrentDatetimeString();
		var currentIP = getsecurityAdvice().getIP();
		
		var markAdvice = getmarkAdvice();
		
		var sql = ""; 
		var queryObj = ""; 
		
		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			sql = "SELECT 
						 t_course.mark_mode mark_mode_c, 
						 t_term.academic_year, 
						 t_term.academic_term, 
						 t_course.course_name, 
						 t_course.course_credit,
						 t_student_mark.mark_mode mark_mode_s, 
						 t_student_mark.mark_result, 
						 t_student_mark.mark_resit,
						 t_student_mark.mark_note, 
						 t_student_mark.stu_id, 
						 t_student_mark.cid 
					FROM 
						 t_student_mark 
						 INNER JOIN t_course ON t_course.cid = t_student_mark.cid 
						 INNER JOIN t_term ON t_term.term_id = t_student_mark.term_id 
					WHERE 
						 t_student_mark.scm_id = :markId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			
			var rs_markEntity = queryObj.execute( sql=sql ).getResult();
			
			var markMode = rs_markEntity.mark_mode_c;
			var mark = event.getArg("Mark");
			var markNote = event.getArg("MarkNote");
			
			var credit = rs_markEntity.course_credit;
			
			/* 根据成绩备注矫正分数 */
			if ( markNote eq "2" ) { /* 2 - 缺考 */ scroll = -1; }
			if ( markNote eq "3" ) { /* 3 - 缓考 */ scroll = -1; }
			if ( markNote eq "4" ) { /* 4 - 免修 */ scroll = -1; }
			if ( markNote eq "9" ) { /* 9 - 违纪 */ scroll = 0; }
			
			/* 根据成绩计分模式调整分数 */
			switch ( markMode ) {
				
				case "0":
					/* 百分制最多保留2位小数 */
					if ( markNote eq "1" ) {
						scroll = round( mark * 10 ) / 10;
					}					
					break;
					
				case "2":
					/* 二级制则转换 Y N */
					if ( markNote eq "Y" ) {
						scroll = 60; 
						markNote = "1";
					}
					else if ( markNote eq "N" ) {
						scroll = 0; 
						markNote = "1";
					}
					break;
					
				case "4":
					/* 五级制则转换 A B C D */
					
					if ( markNote eq "A" ) {
						scroll = 95; 
						markNote = "1";
					}
					else if ( markNote eq "B" ) {
						scroll = 85; 
						markNote = "1";
					}
					else if ( markNote eq "C" ) {
						scroll = 75; 
						markNote = "1";
					}
					else if ( markNote eq "D" ) {
						scroll = 65; 
						markNote = "1";
					}else if ( markNote eq "E" ) {
						scroll = 0; 
						markNote = "1";
					}
					break;
				
			}
			
			/* 若成绩备注为 缓考 则设置 补考成绩上限为最大值 */
			if ( markNote eq "3" ) { /* 3 - 缓考 */ 
				 markResitLimit = 100;
			}
			else {
				/* 否则设置为默认值 */
				markResitLimit = 100;
			}
			
			if( scroll lt 60 ){
				credit = 0;	
			}
			
			/* 第一步 生成成绩变更审计记录 */
			var logId = sequenceStudentMarkAduit.getNextID();
			
			sql = "INSERT INTO t_mark_aduit(
								opid, tch_id, 
								stu_id, cid, 
								op_type, op_ts, 
								op_ip, operation
							)VALUES(
								:operId, :teacherId, 
								:studentId, :courseId, 
								:operation, :timeStamp, 
								:ip, :description
							)";
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="operId", value=logId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="studentId", value=rs_markEntity.stu_id, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="courseId", value=rs_markEntity.cid, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="operation", value="EDF", cfsqltype="cf_sql_char" );
			queryObj.addParam( name="timeStamp", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="ip", value=currentIP, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="description", value="修改 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 正考成绩, 将 " & markAdvice.getMark( rs_markEntity.mark_mode_s, rs_markEntity.mark_result, rs_markEntity.mark_note ) & " 变更为 " & markAdvice.getMark( markMode, scroll, markNote ), cfsqltype="cf_sql_varchar" );
			
			queryObj.execute( sql=sql );
			
			
			
			/* 第二步 变更成绩历史记录 */
			
			var theCreditPoint = markAdvice.getMarkCredit( markMode, rs_markEntity.course_credit, scroll, rs_markEntity.mark_resit, markResitLimit); /*更新绩点*/
			if( theCreditPoint eq 0){
				credit = 0;	
			}
			
			var creditPoint_o = credit * theCreditPoint;
			
			sql = "UPDATE t_student_mark 
					  SET 
						  mark_resit_limit = :markResitLimit, 
						  mark_mode = :markMode, 
						  mark_result = :markResult, 
						  mark_note = :markNote,
						  prop_id = :propId, 
						  credit_point = :theCreditPoint,
						  term_score = :markResult,
						  credit = :credit,
						  grade_point = :theCreditPoint,
						  credit_point_o = :creditPoint_o 
					  WHERE 
						  scm_id = :markId";
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="markResitLimit", value=markResitLimit, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="markMode", value=markMode, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResult", value=scroll, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="markNote", value=markNote, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="propId", value=event.getArg("PropID"), cfsqltype="cf_sql_char" );
			queryObj.addParam( name="theCreditPoint", value=theCreditPoint, cfsqltype="cf_sql_decimal", scale=4 );
			queryObj.addParam( name="credit", value=credit, cfsqltype="cf_sql_integer" );
			queryObj.addParam( name="creditPoint_o", value=creditPoint_o, cfsqltype="cf_sql_varchar");
		
			queryObj.execute( sql=sql );
			
			var passArgs = structNew();
			structInsert( passArgs, "STU", rs_markEntity.stu_id, true );

			event.setArgs( passArgs );
			
		}
		
	}
	
	
	/**
	* @hint "更新补考成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function updateResit( required MachII.framework.Event event ) output=false {
		
		var sequenceStudentMarkAduit = getsequenceStudentMarkAduit();
		
		var markId = event.getArg("MarkID");
		
		var tchId = getsessionAdvice().getAutherUserID();
		
		var currentTS = getdatetimeAdvice().getCurrentDatetimeString();
		var currentIP = getsecurityAdvice().getIP();
		
		var markAdvice = getmarkAdvice();
		
		var sql = "";
		var queryObj = ""; 
		
		
		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			sql = "SELECT 
						 t_course.mark_mode mark_mode_c, 
						 t_student_mark.mark_resit_limit,
						 t_term.academic_year, 
						 t_term.academic_term, 
						 t_course.course_name, 
						 t_course.course_credit, 
						 t_student_mark.mark_mode mark_mode_s, 
						 t_student_mark.mark_resit, 
						 t_student_mark.mark_result, 
						 t_student_mark.mark_renote, 
						 t_student_mark.stu_id, 
						 t_student_mark.cid 
					FROM 
						 t_student_mark 
						 INNER JOIN t_course ON t_course.cid = t_student_mark.cid 
						 INNER JOIN t_term ON t_term.term_id = t_student_mark.term_id 
					WHERE 
						 t_student_mark.scm_id = :markId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );
			
			var rs_markEntity = queryObj.execute( sql=sql ).getResult();
			
			var markMode = rs_markEntity.mark_mode_c;
			var mark = event.getArg("MarkResit");
			var markNote = event.getArg("MarkResitNote");
			
			var credit = rs_markEntity.course_credit;
			
			/* 根据成绩备注矫正分数 */
			if ( markNote eq "2" ) { /* 2 - 缺考 */ scroll = 0; }
			//if ( markNote eq "9" ) { /* 9 - 违纪 */ scroll = 0; }
			
			/* 根据成绩计分模式调整分数 */
			switch ( markMode ) {
				
				case "0":
					/* 百分制最多保留2位小数 */
					if ( markNote eq "1" ) {
						scroll = round( mark * 10 ) / 10;
					}					
					break;
					
				case "2":
					/* 二级制则转换 Y N */
					if ( markNote eq "Y" ) {
						scroll = 60; 
						markNote = "1";
					}
					else if ( markNote eq "N" ) {
						scroll = 0; 
						markNote = "1";
					}
					
					else if ( markNote eq "S" ) {
						scroll = -1; 
						markNote = "1";
					}
					break;
					
				case "4":
					/* 五级制则转换 A B C D */
					if ( markNote eq "A" ) {
						scroll = 95; 
						markNote = "1";
					}
					else if ( markNote eq "B" ) {
						scroll = 85; 
						markNote = "1";
					}
					else if ( markNote eq "C" ) {
						scroll = 75; 
						markNote = "1";
					}
					else if ( markNote eq "D" ) {
						scroll = 65; 
						markNote = "1";
					}
					else if ( markNote eq "E" ) {
						scroll = 0; 
						markNote = "1";
					}
					else if ( markNote eq "F" ) {
						scroll = -1; 
						markNote = "1";
					}
					break;
			
			}
			
			/*if ( scroll gt rs_markEntity.mark_resit_limit ) {
				scroll = rs_markEntity.mark_resit_limit;
			}*/
			
			if( scroll lt 60 ){
				credit = 0;	
			}
			
			
			/* 第一步 生成成绩变更审计记录 */
			var logId = sequenceStudentMarkAduit.getNextID();
			
			sql = "INSERT INTO t_mark_aduit(
								opid, tch_id, 
								stu_id, cid, 
								op_type, op_ts, 
								op_ip, operation
							)VALUES(
								:operId, :teacherId, 
								:studentId, :courseId, 
								:operation, :timeStamp, 
								:ip, :description
							)";
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="operId", value=logId, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="teacherId", value=tchId, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="studentId", value=rs_markEntity.stu_id, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="courseId", value=rs_markEntity.cid, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="operation", value="EDR", cfsqltype="cf_sql_char" );
			queryObj.addParam( name="timeStamp", value=currentTS, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="ip", value=currentIP, cfsqltype="cf_sql_varchar" );
			queryObj.addParam( name="description", value="修改 " & rs_markEntity.academic_year & "-" & rs_markEntity.academic_term & "学期《" & rs_markEntity.course_name & "》 补考成绩, 将 " & markAdvice.getMarkResit( rs_markEntity.mark_mode_s, rs_markEntity.mark_resit, rs_markEntity.mark_renote, rs_markEntity.mark_resit_limit ) & " 变更为 " & markAdvice.getMarkResit( markMode, scroll, markNote, rs_markEntity.mark_resit_limit ), cfsqltype="cf_sql_varchar" );
			
			queryObj.execute( sql=sql );
			
			
			/* 第二步 变更成绩历史记录 */
			var theCreditPoint = markAdvice.getMarkCredit( markMode, rs_markEntity.course_credit, rs_markEntity.mark_result, scroll, rs_markEntity.mark_resit_limit); /*更新绩点*/
			
			if( theCreditPoint eq 0){
				credit = 0;	
			}
			
			var creditPoint_o = credit * theCreditPoint;
			
			sql = "UPDATE t_student_mark 
					  SET 
						  mark_mode = :markMode, 
						  mark_renote = :markResitNote, 
						  mark_resit = :markResit, 
						  credit_point = :theCreditPoint,
						  term_score = :markResit,
						  credit = :credit,
						  grade_point = :theCreditPoint,
						  credit_point_o = :creditPoint_o   
					  WHERE 
						  scm_id = :markId";
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="markId", value=markId, cfsqltype="cf_sql_varchar" );  
			queryObj.addParam( name="markMode", value=markMode, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResitNote", value=markNote, cfsqltype="cf_sql_char" );
			queryObj.addParam( name="markResit", value=scroll, cfsqltype="cf_sql_decimal", scale=2 );
			queryObj.addParam( name="theCreditPoint", value=theCreditPoint, cfsqltype="cf_sql_decimal", scale=4 );
			queryObj.addParam( name="credit", value=credit, cfsqltype="cf_sql_integer" );
			queryObj.addParam( name="creditPoint_o", value=creditPoint_o, cfsqltype="cf_sql_varchar");
		
			queryObj.execute( sql=sql );
			
			
			var passArgs = structNew();
			structInsert( passArgs, "STU", rs_markEntity.stu_id, true );

			event.setArgs( passArgs );
			
		}
		
	}
	
	
	/**
	* @hint "更新学生HSK成绩"
	* 
	* @event "MachII Event Object"
	*/
	public void function updateHSK( required MachII.framework.Event event ) output=false {
		
		var studentId = event.getArg("STU");

		var sql = ""; 
		var queryObj = ""; 
		
		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			/* 学生信息 */
			/* 学生学籍信息 */
			sql = "SELECT  b.hsk_score   
					FROM 
						 t_student_status b 
					WHERE 
						 b.stu_id = :studentId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" );
			
			var rs_student = queryObj.execute( sql=sql ).getResult();
			
			var hskScore = rs_student.hsk_score;
		
			content = "";
			 
			 if( hskScore NEQ event.getArg("HSK")){
				 
				 content = content & "HSK成绩由 " & hskScore & " 修改为 " & event.getArg("HSK") & " ;";	
				 
			 }
			 
			 hskScore = event.getArg("HSK");
			
			
			sql = "UPDATE t_student_status SET 
						  hsk_score = :hskScore   
					WHERE 
						  stu_id = :studentId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" ); 
			queryObj.addParam( name="hskScore", value=hskScore, cfsqltype="cf_sql_varchar" ); 
			
			queryObj.execute( sql=sql );
			
			if( content neq "" ){
				logFactory.writeLog("6",content,studentId);
			}
			
			event.setArg("STU", studentId);

		}
	}
	
	/**
	* @hint "更新学生毕业时间"
	* 
	* @event "MachII Event Object"
	*/
	public void function updateGradTime( required MachII.framework.Event event ) output=false {
		
		var studentId = event.getArg("STU");

		var sql = ""; 
		var queryObj = ""; 
		
		/* Every SQL operation is TRANSACATION*/
		transaction {
			
			/* 学生信息 */
			/* 学生学籍信息 */
			sql = "SELECT  b.grad_date    
					FROM 
						 t_student b 
					WHERE 
						 b.stu_id = :studentId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" );
			
			var rs_student = queryObj.execute( sql=sql ).getResult();
			
			var gradDate = rs_student.grad_date;
		
			content = "";
			 
			 if( gradDate NEQ event.getArg("gradDate")){
				 
				 content = content & "毕业时间由 " & gradDate & " 修改为 " & event.getArg("gradDate") & " ;";	
				 
			 }
			 
			 hskScore = event.getArg("HSK");
			
			
			sql = "UPDATE t_student SET 
						  grad_date = :gradDate   
					WHERE 
						  stu_id = :studentId "; 
			
			queryObj = new Query( datasource=application.dnsMaster );
			queryObj.addParam( name="gradDate", value=event.getArg("gradDate"), cfsqltype="cf_sql_varchar" ); 
			queryObj.addParam( name="studentId", value=studentId, cfsqltype="cf_sql_varchar" ); 
			
			queryObj.execute( sql=sql );
			
			if( content neq "" ){
				logFactory.writeLog("6",content,studentId);
			}
			
			event.setArg("STU", studentId);

		}
	}
	
}

</cfscript>